/**
 * OSAmI: Open Source Ambient Intelligence
 * Copyright (C) 2010 UJF.
 * Contact: osami-general@osami-commons.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 */

package org.osami.gateway.mediator.drools;

import static org.osami.gateway.sensor.SenseData.DEFAULT_DATA_KEY;

import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.osami.gateway.sensor.SenseData;
import org.osami.gateway.type.Temperature;
import org.osgi.service.log.LogService;
import org.ow2.jasmine.rules.api.IDroolsWorkingMemory;
import org.ow2.jasmine.rules.api.IDroolsWorkingMemoryPool;

import fr.liglab.adele.cilia.Data;
import fr.liglab.adele.cilia.framework.IProcessor;

public class MediatorDrools implements IProcessor {

    // TODO replace with a global variable.
    private static final String GATEWAY_ID = "B1-163";

    private final String DEFAULT_MEMORY_NAME = "default";

    /**
     * Drools Service, injected by iPOJO.
     */
    private IDroolsWorkingMemory droolmem;

    /**
     * Logger, injected by iPOJO.
     */
    private LogService logger;

    /**
     * Add the Temperature object to the drools working memory.
     */
    public List process(List dataset) {
        final Iterator i = dataset.iterator();
        Temperature temperature = null;
        Object sensedata;
        double average = 0;
        double count = 0;

        // Get the data
        // TODO check the unit and convert if needed
        while (i.hasNext()) {
            Data data = (Data) i.next();
            sensedata = data.getProperty(DEFAULT_DATA_KEY);
            try {
                average += ((SenseData) sensedata).getValue();
                count++;
            } catch (NullPointerException ne) {
                logger.log(LogService.LOG_WARNING, "The property of key: " + DEFAULT_DATA_KEY + " does not exist, bad data", ne);
            } catch (ClassCastException ce) {
                logger.log(LogService.LOG_WARNING, "The property of key: " + DEFAULT_DATA_KEY + " is not a valid SenseData object, bad data", ce);
            }

        }

        // Add the Temperature average to the Drools memory
        try {
            if (count > 0) {
                average /= count;
                temperature = new Temperature(average, GATEWAY_ID);
                droolmem.insert(temperature);
                logger.log(LogService.LOG_INFO, "Average temperature has been send to drools: " + count + " temperature collected, average: "
                        + average);
            }
        } catch (Exception e) {
            logger.log(LogService.LOG_ERROR, "An exception has been reached while adding the temperature average to the drools memory.", e);
        }

        // For test purpose
        if (temperature != null) {
            return Collections.singletonList(new Data(temperature));
        } else {
            return Collections.EMPTY_LIST;
        }
    }

    private void bindDroolsMemoryPool(IDroolsWorkingMemoryPool pool) {
        droolmem = pool.get(DEFAULT_MEMORY_NAME);

        if (droolmem == null) {
            throw new RuntimeException("The DroolsWorkingMemory " + DEFAULT_MEMORY_NAME + "cannot be found ! mediator down ");
        }
    }

    private void stop() {
        droolmem = null;
    }

}
